package io.filecopy;

import console.ConsoleTable;
import console.ConsoleTable.Alignment;


public class ProgressLogger {

  private long copiedBytes;

  private int copiedFiles;

  private int createdDirectories;

  private long deletedBytes;

  private int deletedFiles;

  private int deletionFails;

  private long deletionFailsInBytes;

  private int failedCopies;

  private long failedCopiesInBytes;

  private int failedDirectoryCreations;

  private int failedModificationTimeChanges;

  private int failedReplacements;

  private long failedReplacementsInBytes;

  private int failedTouches;

  private long replacedBytes;

  private int replacedFiles;

  private int succededTouches;

  public void copyFailed(long size) {
    failedCopies++;
    failedCopiesInBytes += size;
  }

  public void copySucceded(long size) {
    copiedFiles++;
    copiedBytes += size;
  }

  public void directoryCreated() {
    createdDirectories++;
  }

  public void directoryCreationFailed() {
    failedDirectoryCreations++;
  }

  public void fileDeleted(long size) {
    deletedFiles++;
    deletedBytes += size;
  }

  public void fileDeletionFailed(long size) {
    deletionFails++;
    deletionFailsInBytes += size;
  }

  public long getCopiedBytes() {
    return copiedBytes;
  }

  public int getCopiedFiles() {
    return copiedFiles;
  }

  public int getCreatedDirectories() {
    return createdDirectories;
  }

  public long getDeletedBytes() {
    return deletedBytes;
  }

  public int getDeletedFiles() {
    return deletedFiles;
  }

  public int getDeletionFails() {
    return deletionFails;
  }

  public long getDeletionFailsInBytes() {
    return deletionFailsInBytes;
  }

  public int getFailedCopies() {
    return failedCopies;
  }

  public long getFailedCopiesInBytes() {
    return failedCopiesInBytes;
  }

  public int getFailedDirectoryCreations() {
    return failedDirectoryCreations;
  }

  public int getFailedModificationTimeChanges() {
    return failedModificationTimeChanges;
  }

  public int getFailedReplacements() {
    return failedReplacements;
  }

  public long getFailedReplacementsInBytes() {
    return failedReplacementsInBytes;
  }

  public int getFailedTouches() {
    return failedTouches;
  }

  public long getReplacedBytes() {
    return replacedBytes;
  }

  public int getReplacedFiles() {
    return replacedFiles;
  }

  public int getSuccededTouches() {
    return succededTouches;
  }

  public void modificationTimeChangeFailed() {
    failedModificationTimeChanges++;
  }

  public void replaceFailed(long size) {
    failedReplacements++;
    failedReplacementsInBytes += size;
  }

  public void replaceSucceded(long size) {
    replacedFiles++;
    replacedBytes += size;
  }

  public void touchFailed() {
    failedTouches++;
  }

  public void touchSucceded() {
    succededTouches++;
  }

  public void printInfo(PreparedJob job) {
    ConsoleTable table = new ConsoleTable(3);
    table.setAlignment(1, Alignment.RIGHT);
    table.setAlignment(2, Alignment.CENTER);
    table.setColumnNames("Task", "Count", "Percent");
    addRow(table, "directories created" , createdDirectories, job.getNumberOfDirectoriesToCreate(), false);
    addRow(table, "touches"  ,succededTouches, job.getNumberOfTouchesToPerform(), false);
    addRow(table, "copied files"  ,copiedFiles, job.getFilesToCopy(), false);
    addRow(table, "copied bytes"  ,copiedBytes, job.getBytesToCopy(), false);
    addRow(table, "replaced files" ,replacedFiles, job.getFilesToReplace(), false);
    addRow(table, "replaced bytes" ,replacedBytes, job.getBytesToReplace(), false);
    addRow(table, "deleted files" ,deletedFiles, job.getFilesToDelete(), false);
    addRow(table, "deleted bytes" ,deletedBytes, job.getBytesToDelete(), false);
    addRow(table, "failed directory creations" , failedDirectoryCreations, job.getNumberOfDirectoriesToCreate(), true);
    addRow(table, "failed touches" , failedTouches, job.getNumberOfTouchesToPerform(), true);
    addRow(table, "failed copies" , failedCopies, job.getFilesToCopy(), true);
    addRow(table, "failed copies (bytes)" , failedCopiesInBytes, job.getBytesToCopy(), true);
    addRow(table, "failed deletions" , deletionFails, job.getFilesToDelete(), true);
    addRow(table, "failed deletions (bytes)" , deletionFailsInBytes, job.getBytesToDelete(), true);
    addRow(table, "failed replacements" , failedReplacements, job.getFilesToReplace(), true);
    addRow(table, "failed replacements (bytes)" , failedReplacementsInBytes, job.getBytesToReplace(), true);
    addRow(table, "failed modification time changes" , failedModificationTimeChanges);
    System.out.println(table.toString());
  }
  
  private void addRow(ConsoleTable table , String key, long current, long total, boolean failiure){
    table.addRow(key, Long.toString(current) + "/" + total, "(" + (total == 0?(failiure?0:100):(100 * current / total)) + "%)");
  }

  private void addRow(ConsoleTable table , String key, long current){
    table.addRow(key, Long.toString(current), null);
  }
}